package spherical_tessellation_test;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GraphicsConfiguration;

import javax.media.j3d.AmbientLight;
import javax.media.j3d.Appearance;
import javax.media.j3d.BoundingSphere;
import javax.media.j3d.BranchGroup;
import javax.media.j3d.Canvas3D;
import javax.media.j3d.PointLight;
import javax.media.j3d.Shape3D;
import javax.media.j3d.TriangleArray;
import javax.swing.JFrame;
import javax.vecmath.Color3f;
import javax.vecmath.Point3d;
import javax.vecmath.Point3f;

import com.sun.j3d.utils.universe.SimpleUniverse;

public class PlanetRender extends JFrame {

	private static final long serialVersionUID = -6911175101166329013L;

	private PlanetGeometry planet;

	/**
	 * Sets the JFrame parameters and sets up the branch group for the scene.
	 * Sets up a default viewing platform and adds the canvas 3d to the frame.
	 */
	public PlanetRender(PlanetGeometry planet) {
		super("Planet Render");

		this.planet = planet;

		this.setLayout(new BorderLayout());
		this.setSize(800, 600);
		this.setLocation(300, 300);
		this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

		GraphicsConfiguration config = SimpleUniverse
				.getPreferredConfiguration();
		Canvas3D canvas3D = new Canvas3D(config);
		this.add(canvas3D);

		BranchGroup scene = createSceneGraph();

		SimpleUniverse simpleU = new SimpleUniverse(canvas3D);
		simpleU.getViewingPlatform().setNominalViewingTransform();

		scene.compile();

		simpleU.addBranchGraph(scene);
	}

	/**
	 * Creates a triangle array with the planet geometry.
	 * 
	 * @return The branch group containing all scene objects.
	 */
	private BranchGroup createSceneGraph() {
		BranchGroup scene = new BranchGroup();

		planet.updateTriangleList();

		TriangleArray triangles = new TriangleArray(3 * planet.getTriangles()
				.size(), TriangleArray.COORDINATES);

		for (SurfaceTriangle t : planet.getTriangles()) {
			triangles.setCoordinate(3, t.getV0().getWorldCoordinate());
			triangles.setCoordinate(2, t.getV1().getWorldCoordinate());
			triangles.setCoordinate(1, t.getV2().getWorldCoordinate());
		}

		scene.addChild(new Shape3D(triangles, new Appearance()));

		PointLight light = new PointLight(
				new Color3f(new Color(255, 255, 255)), new Point3f(0.3f, 1.0f,
						1.0f), new Point3f(1.0f, 0.0f, 0.0f));
		light.setInfluencingBounds(new BoundingSphere(new Point3d(0, 0, 0),
				100.0f));

		AmbientLight aLight = new AmbientLight(new Color3f(new Color(255, 255,
				255)));
		aLight.setInfluencingBounds(new BoundingSphere(new Point3d(0, 0, 0),
				100.0f));

		scene.addChild(aLight);
		scene.addChild(light);

		return scene;
	}

	@Override
	public void dispose() {
		System.exit(0);
	}

	/**
	 * Creates a new JFrame and makes it visible.
	 * 
	 * @param args
	 */
	public static void main(String[] args) {
		PlanetRender world = new PlanetRender(new PlanetGeometry());
		world.setVisible(true);
	}

}
